﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;

namespace Duellum.Core.DuelCoreTypes
{
	public static class DuelCoreTypesExt
	{
		static public IEnumerable<string> EnumerateType(this Type type)
		{
		    return
		        type
		        .GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy)
		        .Select(m => (string)m.GetValue(null));
		}
	}

	public static class Gun
	{
		public const string Base			= "Gun.Base";
		
		public const string BlasterLauncher	= "Gun.BlasterLauncher";
		public const string Blunderbuss		= "Gun.Blunderbuss";
		public const string Flamethrower	= "Gun.Flamethrower";
		public const string Machinegun		= "Gun.Machinegun";
		public const string Minigun			= "Gun.Minigun";
		public const string ParalizerGun	= "Gun.ParalizerGun";
		public const string Pistol			= "Gun.Pistol";
		public const string Poisongun		= "Gun.Poisongun";
		public const string Revolver		= "Gun.Revolver";
		public const string RicochetGun		= "Gun.RicochetGun";
		public const string Rifle			= "Gun.Rifle";
		public const string RocketLauncher	= "Gun.RocketLauncher";
		public const string Shotgun			= "Gun.Shotgun";
		public const string Submachinegun	= "Gun.Submachinegun";
		public const string TeleportationGun= "Gun.TeleportationGun";
		public const string PredatorDisk	= "Weapon.PredatorDisk";
		
		static public IEnumerable<string> Enumerate() { return DuelCoreTypesExt.EnumerateType(typeof(Gun)); }
	}

	public static class Dec
	{
		public const string Base		= "Dec.Base";

		public const string GreenBlood	= "Dec.GreenBlood";
		public const string RedBlood	= "Dec.RedBlood";
		public const string YellowBlood	= "Dec.YellowBlood";
		
		static public IEnumerable<string> Enumerate() { return DuelCoreTypesExt.EnumerateType(typeof(Dec)); }
	}
}

namespace Duellum.Core
{
	[DuelPlugin("Duellum Core Plugin")]
	public class CorePlugin : IDuelPlugin
	{
		private DuelPluginXmlConfigReader xmlConfig;
		private DuelDomain domain;
		
		DuelDomain IDuelPlugin.Domain
		{
			get { return domain; }
			set {
				if (domain != null) throw new InvalidOperationException("Domain already set");
				if (value == null) throw new ArgumentNullException("value");
				domain = value;
			}
		}
		
		void ISupportInitialize.BeginInit()
		{
			xmlConfig = new DuelPluginXmlConfigReader(
				domain,
				new Uri("pack://siteoforigin:,,,/config/coretypes.xml", UriKind.Absolute)
			);
		}
		
		void ISupportInitialize.EndInit()
		{
			xmlConfig.Dispose();
			xmlConfig = null;
		}

		IEnumerable<DuelPluginName> IDuelPlugin.GetReferencedPlugins()
		{
			return null;
		}

		IEnumerable<DuelType> IDuelPlugin.GetTypes()
		{
			////var typeDict = DuelSerializer.GetXmlTypeDictionary(Assembly.GetExecutingAssembly());
			
			////var uri = new Uri("/CorePlugin/core.xml", UriKind.RelativeOrAbsolute);
			////var uri = new Uri("pack://application:,,,/CorePlugin/core.xml", UriKind.RelativeOrAbsolute);
			////var uri = new Uri("pack://application:,,,/Duellum.Core;component/plugins/core.xml", UriKind.RelativeOrAbsolute);
			//var uri = new Uri("pack://siteoforigin:,,,/config/coretypes.xml", UriKind.Absolute);
			//XDocument xdoc;
			//using (var xmlStream = DuelResources.GetStreamFromUri(uri)) {
			//    xdoc = XDocument.Load(XmlReader.Create(xmlStream));
			//}
			
			//var types = xdoc.XPathSelectElements("/duellum/types/*");
			//using (var serializer = new DuelSerializer()) {
			//    return (
			//        from x in types
			//        select serializer.DeserializeDuelType(x)//, typeDict)
			//    ).ToArray();
			//}
			return xmlConfig.GetTypes();
		}

		//IEnumerable<DuelDecoration> IDuelPlugin.GetExtendedTypes()
		//{
		//    return xmlConfig.GetExtendedTypes();
		//}

		IEnumerable<DuelDecoration> IDuelPlugin.GetDecorations()
		{
			return xmlConfig.GetDecorations();
		}
		
		public void Dispose()
		{
			if (xmlConfig != null) xmlConfig.Dispose();
		}
	}
}
